@echo off
:: 设置cmd窗口标题和主题
call lib\theme "file upload"

:: 这个脚本主要用作将本地jar上传到远程linux服务器（有则覆盖），需要配置下相关参数即可
:: 理论上，通过修改参数，可以实现本地任意文件，上传到远程服务器任意位置
:: 如果远程服务器上已经有相同名称的文件，会先将其下载备份，然后再执行上传和覆盖
:: 备份文件位于.\download\backup\文件夹下，对于重要的文件，请妥善保管备份文件，勿轻易删除

:: ==================参数列表-开始==========================
:: 远程Linux服务器IP
set HOST=%~1
if "%HOST%" == "" (
	call print\error %LOG_MODULE% "[CHECK] the remote host is null"
 	call print\info %LOG_MODULE% ""
	call print\info %LOG_MODULE% "================= END =================="
	call print\info %LOG_MODULE% ""
 	pause
    exit /b 1
)
:: 远程Linux服务器用户名
set USER=%~2
if "%USER%" == "" (
	call print\error %LOG_MODULE% "[CHECK] the user name is null"
 	call print\info %LOG_MODULE% ""
	call print\info %LOG_MODULE% "================= END =================="
	call print\info %LOG_MODULE% ""
 	pause
    exit /b 1
)

:: 本地待上传的文件所在目录，%cd%表示当前工作目录
set LOCAL_DIR=%~3
if "%LOCAL_DIR%" == "" (
	call print\error %LOG_MODULE% "[CHECK] the local dir is null"
 	call print\info %LOG_MODULE% ""
	call print\info %LOG_MODULE% "================= END =================="
	call print\info %LOG_MODULE% ""
 	pause
    exit /b 1
)
:: 转换斜杠符号，将/替换为\
set LOCAL_DIR=%LOCAL_DIR:/=\%
:: 丢弃最后一个斜杠
if "%LOCAL_DIR:~-1%"=="\" set "LOCAL_DIR=%LOCAL_DIR:~0,-1%"
:: 变量为空则重新将斜杠加上
if "%LOCAL_DIR%" == "" (
	:: 斜杠表示当前盘符的根目录
	set LOCAL_DIR=\
)


:: 本地待上传的文件全名
set UPLOAD_FILE_NAME=%~4


:: 远程目标目录
set REMOTE_DIR=%~5
:: 如果远程目录参数为空，则默认上传到
if "%REMOTE_DIR%" == "" (
	set REMOTE_DIR=/home/%USER%/upload
)
:: 转换斜杠符号，将\替换为/
set REMOTE_DIR=%REMOTE_DIR:\=/%
if "%REMOTE_DIR:~-1%"=="/" set "REMOTE_DIR=%REMOTE_DIR:~0,-1%"
:: 变量为空则重新将斜杠加上
if "%REMOTE_DIR%" == "" (
	set REMOTE_DIR=/
)
:: ==================参数列表-结束==========================



:: 备份目录（上传文件时，如果远程存在相同文件，则先将其备份，远程文件下载后会放到这个备份目录下面）
set BACKUP_DIR=%cd%\download\backup
:: 如果没有该目录，则先创建
call lib\tryMkdir "%BACKUP_DIR%"

:: 获取当前小时
set HOUR=%TIME:~0,2%
:: 小时可能是12小时制，如果小时数字小于10就将数字前的一个空格替换成0
if %HOUR% lss 10 (set HOUR=0%HOUR:~1,2%)
:: 获取当前日期和时间，格式为yyyyMMddHHmmss
set DATETIME_STR=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%%HOUR%%TIME:~3,2%%TIME:~6,2%
:: 随机字符串，包含日期时间和随机数
set RANDOM_STR=%DATETIME_STR%_%RANDOM%
:: 定义临时文件（用于将 plink 命令的输出结果保存到临时文件中）
set TEMP_FIME=temp\temp_upload_%RANDOM_STR%.txt
call lib\tryMkdir temp

:: 日志模块名（会作为日志文件名的一部分）
set LOG_MODULE=upload

:: 打印基本信息
call print\info %LOG_MODULE% "=========== BEGIN FILE UPLOAD =========="               
call print\info %LOG_MODULE% ""                                                                                           
call print\info %LOG_MODULE% "    REMOTE_HOST: %HOST%"      
call print\info %LOG_MODULE% "    LOCAL_FILE: %LOCAL_DIR%\%UPLOAD_FILE_NAME%"                     
call print\info %LOG_MODULE% "    REMOTE_DIR: %REMOTE_DIR%"            
call print\info %LOG_MODULE% ""                                              
call print\info %LOG_MODULE% "----------------------------------------"               
call print\info %LOG_MODULE% "" 



:: 输入远程Linux服务器登录密码
:passwordInput
:: PASSWORD 脚本会自动输入密码
call lib\passwordInput "Please enter the remote host login password" "PASSWORD"
if "%PASSWORD%" == "" (
	goto passwordInput
)


:: 判断本地文件是否存在，不存在则提示并退出
if not exist "%LOCAL_DIR%\%UPLOAD_FILE_NAME%" (
 	call print\error %LOG_MODULE% "[CHECK] the local file is not exist"
 	call print\info %LOG_MODULE% ""
	call print\info %LOG_MODULE% "================= END =================="
	call print\info %LOG_MODULE% ""
 	pause
    exit /b 1
)
call print\error %LOG_MODULE% "[CHECK] the local file is ready"


call print\info %LOG_MODULE% "[BACKUP] if the same file exists on the remote server, back it up locally"
:: 调用plink工具，创建远程文件夹，并查询远程文件夹中是否存在相同名字的文件, 将查询结果保存到临时文件中 0 表示文件存在 空表示文件不存在
lib\plink -batch -pw %PASSWORD% %USER%@%HOST% "mkdir -p %REMOTE_DIR%; test -e %REMOTE_DIR%/%UPLOAD_FILE_NAME% && echo 0" > %TEMP_FIME%
if "%errorlevel%" neq "0" (
	:: 删除临时文件
	del %TEMP_FIME%
	call print\error %LOG_MODULE% "[BACKUP] test file exist failed"
 	call print\info %LOG_MODULE% ""
	call print\info %LOG_MODULE% "================= END =================="
	call print\info %LOG_MODULE% ""
 	pause
    exit /b 1
)
:: 读取临时文件中第一行数据保存到 TEST_FILE_RESULT 中 0 表示文件存在 空表示文件不存在
for /F "delims=" %%H in (%TEMP_FIME%) do set TEST_FILE_RESULT=%%H
:: 删除临时文件
del %TEMP_FIME%
:: 如果远程文件存在，则进行备份
if "%TEST_FILE_RESULT%" equ "0" (
	call print\info %LOG_MODULE% "[BACKUP] There is a file with the same name in the remote server" 
	call print\info %LOG_MODULE% "[BACKUP] remote file: %REMOTE_DIR%/%UPLOAD_FILE_NAME%" 
	call print\info %LOG_MODULE% "[BACKUP] to be backup remote file to local..."
	:: 调用pscp工具命令开始下载备份
	lib\pscp -pw %PASSWORD% %USER%@%HOST%:%REMOTE_DIR%/%UPLOAD_FILE_NAME% %BACKUP_DIR%\backup_%RANDOM_STR%_%UPLOAD_FILE_NAME%
	:: errorlevel 是bat批处理内置变量，表示上一条命令执行是否成功 0：成功 其他非0值表示失败
	if "%errorlevel%" equ "0" (
		:: 二次校验备份的文件是否已经存在本地，不存在则提示并退出
		if not exist %BACKUP_DIR%\backup_%RANDOM_STR%_%UPLOAD_FILE_NAME% (
			call print\error %LOG_MODULE% "[BACKUP] remote file exist but backup file failed. please retry."
			call print\info %LOG_MODULE% ""
			call print\info %LOG_MODULE% "================= END =================="
			call print\info %LOG_MODULE% ""
			pause
			exit /b 1
		)
		call print\info %LOG_MODULE% "[BACKUP] backup file %BACKUP_DIR%\backup_%RANDOM_STR%_%UPLOAD_FILE_NAME%"
		call print\info %LOG_MODULE% "[BACKUP] backup file successful."
	) else (
		call print\error %LOG_MODULE% "[BACKUP] errorlevel: %errorlevel%"
		call print\error %LOG_MODULE% "[BACKUP] backup file failed."
		call print\info %LOG_MODULE% ""
		call print\info %LOG_MODULE% "================= END =================="
		call print\info %LOG_MODULE% ""
		pause
		exit /b 1
	)
)


call print\info %LOG_MODULE% "[UPLOAD] to be upload file to remote..."
:: 调用pscp命令执行上传操作
lib\pscp -pw %PASSWORD% -scp %LOCAL_DIR%\%UPLOAD_FILE_NAME% %USER%@%HOST%:%REMOTE_DIR%/
:: errorlevel 是bat批处理内置变量，表示上一条命令执行是否成功 0：成功 其他非0值表示失败
if "%errorlevel%" neq "0" (
	call print\error %LOG_MODULE% "[UPLOAD] errorlevel: %errorlevel%"
	call print\error %LOG_MODULE% "[UPLOAD] upload failed."
 	call print\info %LOG_MODULE% ""
	call print\info %LOG_MODULE% "================= END =================="
	call print\info %LOG_MODULE% ""
	pause
	exit /b 1
)

call print\info %LOG_MODULE% "[UPLOAD] upload successful."
call print\info %LOG_MODULE% ""
call print\info %LOG_MODULE% "================= END =================="
call print\info %LOG_MODULE% ""

exit /b 0